package com.lb.activity.website.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.lb.activity.mapper.WebArticleMapper;
import com.lb.activity.po.SessionUser;
import com.lb.activity.po.User;
import com.lb.activity.po.WebArticle;
import com.lb.activity.util.ResultUtil;
import com.lb.activity.util.SessionUtil;
import com.lb.activity.util.SnowflakeIdWorker;
import com.lb.activity.util.emumdata.DataEnum;
import com.lb.activity.vo.ArticleVo;
import com.lb.activity.vo.PageVo;
import com.lb.activity.website.service.TextService;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.exception.CosClientException;
import com.qcloud.cos.exception.CosServiceException;
import com.qcloud.cos.model.PutObjectRequest;
import com.qcloud.cos.model.PutObjectResult;
import com.qcloud.cos.model.UploadResult;
import com.qcloud.cos.region.Region;
import com.qcloud.cos.transfer.TransferManager;
import com.qcloud.cos.transfer.Upload;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;

import static java.util.concurrent.Executors.newFixedThreadPool;

/**
 * @author 001030
 */
@Service
@Slf4j
public class TextServiceImpl implements TextService {


    @Value("${qcloud_access_key}")
    private String accessKey;
    @Value("${qcloud_secret_key}")
    private String secretKey;
    @Value("${qcloud_region}")
    private String region;
    @Value("${qcloud_bucketName}")
    private String bucketName;
    @Value("${qcloud_baseurl}")
    private String baseUrl;
    @Autowired
    private SnowflakeIdWorker idWorker;
    @Resource
    private WebArticleMapper webArticleMapper;


    /**
     * 上传文件
     * @param multipartRequest
     * @return
     */
    @Override
    public String uploadFileAndReturnFilePath(MultipartHttpServletRequest multipartRequest) {
        //返回值 文件的url
        String url = "";
        // 1 初始化用户身份信息(secretId, secretKey)
        COSCredentials cred = new BasicCOSCredentials(accessKey, secretKey);
        // 2 设置bucket的区域, COS地域的简称请参照 https://cloud.tencent.com/document/product/436/6224
        // clientConfig中包含了设置region, https(默认http), 超时, 代理等set方法, 使用可参见源码或者接口文档FAQ中说明
        ClientConfig clientConfig = new ClientConfig(new Region(region));
        COSClient cosClient = new COSClient(cred, clientConfig);
        ExecutorService threadPool = newFixedThreadPool(32);

        // 传入一个threadpool, 若不传入线程池, 默认TransferManager中会生成一个单线程的线程池。
        TransferManager transferManager = new TransferManager(cosClient, threadPool);
        try {
            long startTime = System.currentTimeMillis();
            // 3 生成cos客户端
            // bucket的命名规则为{name}-{appid} ，此处填写的存储桶名称必须为此格式
            MultipartFile file = multipartRequest.getFile("file");
            File localFile = new File(System.getProperty("user.dir")+"/"+idWorker.nextId()+".txt");
            if(!localFile.exists()){
                localFile.createNewFile();
            }
            FileUtils.copyInputStreamToFile(file.getInputStream(), localFile);
            /*
            指定要上传到 COS 上对象键
            对象键（Key）是对象在存储桶中的唯一标识。
            */
            String key = file.getOriginalFilename();
            key = idWorker.nextId()+key.substring(key.lastIndexOf(".")).toLowerCase();
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, key, localFile);
            PutObjectResult putObjectResult = cosClient.putObject(putObjectRequest);
            Upload upload = transferManager.upload(putObjectRequest);
            UploadResult uploadResult = upload.waitForUploadResult();
            long endTime = System.currentTimeMillis();
            log.info("used time: " + (endTime - startTime) / 1000);
            log.info(uploadResult.getETag());
            url = baseUrl+key;
            log.info(url);
            localFile.delete();
        }catch (CosServiceException | IOException e) {
            e.printStackTrace();
        } catch (CosClientException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            transferManager.shutdownNow();
            //关闭客户端
            cosClient.shutdown();
        }
        return url;
    }

    /**
     * 添加
     * @param webArticle
     * @param content
     * @return
     */
    @Override
    public ResultUtil addText(WebArticle webArticle, String content) {
        SessionUser sessionUser = SessionUtil.getSessionUser();
        int i = 0;
        if(sessionUser != null){
            User adminUser = sessionUser.getAdminUser();
            webArticle.setId(idWorker.nextId());
            webArticle.setStatus(DataEnum.INSERT_STATUS.getStatus());
            webArticle.setArtCreaterId(adminUser.getId());
            webArticle.setArtCreater(adminUser.getUserName());
            webArticle.setArtContent(content.getBytes());
            i = webArticleMapper.insertSelective(webArticle);
        }
        return ResultUtil.ok(i>0);
    }

    /**
     * 页面集合
     * @param pageVo
     * @return
     */
    @Override
    public ResultUtil texts(PageVo pageVo) {
        PageHelper.startPage(pageVo.getPage(),pageVo.getLimit());
        Example example = new Example(WebArticle.class);
        Example.Criteria criteria = example.createCriteria();
        //按照创建时间排序
        example.setOrderByClause(" status asc , create_time desc ");
        List<WebArticle> webArticles = webArticleMapper.selectByExample(example);
        List<ArticleVo> list = new ArrayList<>();
        webArticles.forEach(art -> {
            ArticleVo articleVo = new ArticleVo();
            BeanUtils.copyProperties(art,articleVo);
            try {
                articleVo.setContent(new String(art.getArtContent(),"utf-8"));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            list.add(articleVo);
        });
        PageInfo<ArticleVo> pageInfo = new PageInfo(list);
        return ResultUtil.build(0,"",Integer.parseInt(pageInfo.getTotal()+""),list);
    }

    /**
     * 删除  ，更新状态
     * @param id
     * @return
     */
    @Override
    public ResultUtil removeData(Long id) {
        WebArticle webArticle = WebArticle.builder().id(id).status(DataEnum.DELETE_STATUS.getStatus()).build();
        int i = webArticleMapper.updateByPrimaryKeySelective(webArticle);
        return ResultUtil.ok(i>0);
    }

    /**
     * 根据ID查询数据
     * @param id
     * @return
     */
    @Override
    public ArticleVo viewDataById(Long id) {
        WebArticle webArticle = webArticleMapper.selectByPrimaryKey(id);
        ArticleVo articleVo = new ArticleVo();
        BeanUtils.copyProperties(webArticle,articleVo);
        try {
            articleVo.setContent(new String(webArticle.getArtContent(),"utf-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return articleVo;
    }

    @Override
    public ResultUtil updateText(ArticleVo articleVo, String content) {
        WebArticle webArticle = WebArticle.builder().build();
        BeanUtils.copyProperties(articleVo,webArticle);
        SessionUser sessionUser = SessionUtil.getSessionUser();
        int i = 0;
        if(sessionUser != null){
            webArticle.setArtContent(content.getBytes());
            i = webArticleMapper.updateByPrimaryKeySelective(webArticle);
        }
        return ResultUtil.ok(i>0);
    }

    /**
     * 置顶文章
     * 注意置顶文章只能有一个
     * @param articleVo
     * @return
     */
    @Override
    public ResultUtil toLockTopText(ArticleVo articleVo) {
        Example example = new Example(WebArticle.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("isTop",DataEnum.DATA_TOP.getStatus());
        List<WebArticle> webArticles = webArticleMapper.selectByExample(example);
        WebArticle webArticle = webArticleMapper.selectByPrimaryKey(articleVo.getId());
        if(webArticle .getStatus().equals(DataEnum.INSERT_STATUS.getStatus())){

            if(webArticles.size() > 0){
                if(webArticles.get(0).getId().equals( articleVo.getId())){
                    webArticle.setIsTop(DataEnum.DATA_NOT_TOP.getStatus());
                }else{
                    return ResultUtil.build(400,"请先取消其他文章置顶");
                }
            }else{
                //更新状态
                if(webArticle.getIsTop().equals(DataEnum.DATA_TOP.getStatus())){
                    //是上架，页面点击的下架
                    webArticle.setIsTop(DataEnum.DATA_NOT_TOP.getStatus());
                }else{
                    webArticle.setIsTop(DataEnum.DATA_TOP.getStatus());
                }
            }
            webArticleMapper.updateByPrimaryKeySelective(webArticle);
            return ResultUtil.ok();
        }else{
            return ResultUtil.build(400,"删除后不可操作");
        }
    }

    /**
     * 设置热门文章
     * 可以设置多个
     * @param articleVo
     * @return
     */
    @Override
    public ResultUtil toLockHotText(ArticleVo articleVo) {
        WebArticle webArticle = webArticleMapper.selectByPrimaryKey(articleVo.getId());
        if(webArticle .getStatus().equals(DataEnum.INSERT_STATUS.getStatus())){
            if(webArticle.getIsHot().equals(DataEnum.DATA_HOT.getStatus())){
                //是上架，页面点击的下架
                webArticle.setIsHot(DataEnum.DATA_NOT_HOT.getStatus());
            }else{
                webArticle.setIsHot(DataEnum.DATA_HOT.getStatus());
            }
            webArticleMapper.updateByPrimaryKeySelective(webArticle);
            return ResultUtil.ok();
        }else{
            return ResultUtil.build(400,"删除后不可操作");
        }

    }


}
